using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using TddGenerator.Core.Domain;
using TddGenerator.Core.Services;

namespace TddGenerator.Core.Services.Impl
{
    public class ClassGenerator : IClassGenerator
    {
        private readonly ITemplateSetRepository repository;
        private readonly IVsIdeService ideService;
        private readonly IProjectRepository projectRepository;
        private readonly ITokenFactory tokenFactory;
        private readonly IConfigurationRepository configurationRepository;

        public ClassGenerator(ITemplateSetRepository repository, IVsIdeService service, IProjectRepository projectRepository, ITokenFactory tokenFactory, IConfigurationRepository configurationRepository)
        {
            this.repository = repository;
            this.ideService = service;
            this.projectRepository = projectRepository;
            this.tokenFactory = tokenFactory;
            this.configurationRepository = configurationRepository;
        }



        public void CreateClasses(ClassToCreate classToCreate)
        {
            TemplateSet templates = this.repository.Get();

            GeneratorConfiguration config = configurationRepository.Get();  
            
            IList<string> folderHiarchy = classToCreate.FolderHierarchy;
            IList<string> implementationFolderHiarchy = new List<string>( classToCreate.FolderHierarchy);
            
            implementationFolderHiarchy.Add(config.ImplementationFolder);
            
            string className = classToCreate.ClassName;

            ideService.CreateFolderHierarchy(classToCreate.ClassProject, folderHiarchy);
            ideService.CreateFolderHierarchy(classToCreate.ClassProject, implementationFolderHiarchy);
            ideService.CreateFolderHierarchy(classToCreate.TestProject, folderHiarchy);

            string implementationClassFilename = classToCreate.ClassName+templates.FileExtension;
            string interfaceFilename = config.InterfacePrefix + className + templates.FileExtension;
            string testClassFilename = className + config.TestSufix + templates.FileExtension;

            ideService.AddFileToFolder(classToCreate.ClassProject, implementationFolderHiarchy, implementationClassFilename, templates.ClassTemplate);
            
            ideService.AddFileToFolder(classToCreate.ClassProject, folderHiarchy, interfaceFilename, templates.InterfaceTemplate);

            ideService.AddFileToFolder(classToCreate.TestProject, folderHiarchy, testClassFilename, templates.TestClass);

            IDictionary<string, string> tokens = tokenFactory.Create(classToCreate, templates,config,implementationFolderHiarchy);

            ideService.ReplaceTokens(classToCreate.ClassProject, implementationFolderHiarchy, implementationClassFilename, tokens);

            ideService.ReplaceTokens(classToCreate.ClassProject, folderHiarchy, interfaceFilename, tokens);

            ideService.ReplaceTokens(classToCreate.TestProject, folderHiarchy, testClassFilename, tokens);
            
        }

    //    private string GetRootNamespace(string project)
    //    {
    //        Project ClassProject = GetProjectInstance(project);

    //        return GetDefaultNamespace(ClassProject);
    //    }

    //    private void CreateFoldersAndAddClassFile(IEnumerable<string> folders, string className, string namespaceName,
    //                                              string projectName, string templateFileName,
    //                                              string templateLanguageName, string FilenameExtension, string interfaceNamespace, string testSuffix)
    //    {
    //        Project ClassProject = GetProjectInstance(projectName);
            
    //        string DefaultNamespace = GetDefaultNamespace(ClassProject);

    //        ProjectItems items = ClassProject.ProjectItems;
    //        foreach (string foldername in folders)
    //        {
    //            ProjectItem folder = GetFolder(foldername, items);
    //            items = folder.ProjectItems;
    //        }

    //        AddCodeFileToFolder(items, className, DefaultNamespace +"."+ namespaceName, templateFileName, templateLanguageName,
    //                            FilenameExtension,interfaceNamespace,testSuffix);

    //    }

    //    private string GetDefaultNamespace(Project ClassProject)
    //    {
    //        string DefaultNamespace = ClassProject.Properties.Item("RootNamespace").Value.ToString();
    //        return DefaultNamespace;
    //    }

    //    private void AddCodeFileToFolder(ProjectItems items, string className, string namespaceName, string templateName,
    //                                     string classLanguage, string FileName,string interfaceNamespace,string testSuffix)
    //    {
    //        Solution2 sol = (Solution2) dte2.Solution;
    //        string dir = Assembly.GetAssembly(this.GetType()).Location;
    //        dir = Path.GetDirectoryName(dir)+"\\";
    //        ProjectItem cutitem = items.AddFromFileCopy(dir + templateName);

    //        cutitem.Name = FileName;
    //        cutitem.Open(Constants.vsViewKindCode);
    //        cutitem.Document.ReplaceText("$concrete$", className, 0);
    //        cutitem.Document.ReplaceText("$concretevariable$", className.Substring(0,1).ToLower()+className.Substring(1,className.Length-1) , 0);
    //        cutitem.Document.ReplaceText("$interface$", "I"+className, 0);
    //        cutitem.Document.ReplaceText("$namespace$", namespaceName, 0);
    //        cutitem.Document.ReplaceText("$interfacenamespace$", interfaceNamespace, 0);
    //        cutitem.Document.ReplaceText("$testsuffix$", testSuffix, 0);
    //        cutitem.Save(cutitem.get_FileNames(0));
    //        cutitem.Document.Activate();
    //    }

    //    private ProjectItem GetFolder(string folderName, ProjectItems ProjectItems)
    //    {
    //        ProjectItem folder = null;
    //        foreach (ProjectItem item in ProjectItems)
    //        {
    //            if (item.Name == folderName)
    //            {
    //                folder = item;
    //                break;
    //            }
    //        }
    //        if (folder == null)
    //        {
    //            string folderDirectoryName = Path.GetDirectoryName( ProjectItems.ContainingProject.FileName)+"\\"+folderName;
    //            if (DirectoryExists(folderDirectoryName))
    //            {
    //                folder = ProjectItems.AddFromDirectory(folderDirectoryName);
    //                //Directory.Delete(folderDirectoryName);
    //            }
    //            else
    //                folder = ProjectItems.AddFolder(folderName, Constants.vsProjectItemKindPhysicalFolder);
                
    //        }
    //        return folder;
    //    }

    //    private bool DirectoryExists(string folderDirectoryName)
    //    {
    //        return System.IO.Directory.Exists(folderDirectoryName);
    //    }

    //    private Project GetProjectInstance(string projectName)
    //    {
    //        Project ClassProject;
    //        foreach (Project item in dte2.Solution.Projects)
    //        {
    //            if (item.Name == projectName)
    //            {
    //                return item;
    //            }
    //        }
    //        return null;
    //    }
    }
}